import turtle
import math
import random
import time

# 初始化窗口
screen = turtle.Screen()
screen.bgcolor("black")
screen.title("3D Dynamic Heart with Turtle")
screen.tracer(0)  # 关闭自动刷新，手动控制动画

# 创建爱心对象
heart = turtle.Turtle()
heart.speed(0)
heart.color("red")
heart.hideturtle()

# 创建粒子列表
particles = []
for _ in range(50):  # 生成50个粒子
    p = turtle.Turtle()
    p.shape("circle")
    p.shapesize(0.3)
    p.color(random.choice(["pink", "yellow", "white", "orange"]))
    p.penup()
    p.goto(random.randint(-300, 300), random.randint(-300, 300))
    particles.append(p)


# 3D 爱心的参数方程（带深度）
def heart_3d(t, scale=1, depth=0):
    x = 16 * (math.sin(t) ** 3) * scale
    y = (13 * math.cos(t) - 5 * math.cos(2 * t) - 2 * math.cos(3 * t) - math.cos(4 * t)) * scale
    z = depth * math.sin(t)  # 模拟深度
    return x, y, z


# 绘制带阴影的立体爱心
def draw_3d_heart(scale, depth):
    heart.clear()
    heart.penup()
    heart.goto(0, -100)  # 调整爱心位置
    heart.pendown()
    heart.begin_fill()
    for t in [i * 0.1 for i in range(0, 63)]:  # 离散化参数方程
        x, y, z = heart_3d(t, scale, depth)
        # 根据深度调整颜色（模拟立体感）
        shade = 1 - abs(z) * 0.1
        heart.color((1.0, 0.2 + shade * 0.3, 0.2 + shade * 0.3))
        heart.goto(x, y + z * 10)  # 通过偏移模拟深度
    heart.end_fill()


# 粒子运动逻辑（环绕路径）
def move_particles():
    for p in particles:
        # 让粒子绕爱心做圆周运动
        angle = random.uniform(0, 2 * math.pi)
        radius = 150 + 50 * math.sin(time.time())  # 动态半径
        x = radius * math.cos(angle)
        y = radius * math.sin(angle) - 50  # 调整中心位置
        p.goto(x, y)
        # 根据位置调整粒子大小（模拟深度）
        p.shapesize(0.3 * (1 + 0.5 * math.sin(angle)))


# 主动画循环
scale = 1.0
depth = 0.0
while True:
    # 更新爱心参数
    scale = 1.0 + 0.2 * math.sin(time.time() * 3)  # 缩放动画
    depth = math.sin(time.time() * 2)  # 深度波动

    # 绘制爱心和粒子
    draw_3d_heart(scale, depth)
    move_particles()

    # 手动刷新画面
    screen.update()
    heart.clear()  # 仅清空爱心（保留粒子轨迹）

    # 控制帧率
    turtle.delay(1)